#include<cstdlib>
#include "func.h"
#include "basic.h"
#include "cli_func.h"
#include <cstring>
#include <iostream>
#include <map>
#include<queue>
#include<stack>
#include <sstream>

struct var_type{
    std::string variable;
    char variable_type;
};
struct return_var_{
    std::string string_;
    char c;
    char s[1000];
    int i;
    float f;

};
std::map<std::string, var_type> yrmem;//map模拟内存空间

char pd_var_type(std::string letter){
    int pd_i=0,pd_f=0,pd_f2=0;
    if(letter.length()==1&&letter[0]>='A'&&letter[0]<='Z')return 'c';
    for(int i=0;i<letter.length();i++)if(!isdigit(letter[i]))pd_i=1;
    if(pd_i==0) return 'i';
    for(int i=0;i<letter.length();i++)
        if(letter[i]=='.'){
            pd_f++;
        }
    
    if(pd_f==1&&letter[0]!='.'&&letter[letter.length()-1]!='.')return 'f';
    
    return 's';
}

return_var_ return_var_val(std::string mes){
    return_var_ tmp;
    tmp.string_=mes;
    tmp.i=atoi(mes.c_str());
    tmp.f=atof(mes.c_str());
    tmp.c=mes[0];
    strcpy(tmp.s,mes.c_str());
    return tmp;
}

void _strcpy(char now[],char old[],int l,int r){
    for(int i=l;i<=r;i++){
        now[i-l]=old[i];
    }
    now[r-l+1]='\0';
}

std::string _to_string(int a){
    std::stringstream ss;
    ss << a;
    return ss.str();
}

std::string cut_strings(char letter[]){

}

//-------------------------------------------------------------

void define_vars(char letter[]){
    int p1=0,p2,p3,p4;
    while(p1<=10){
        if(letter[p1]!=' ')break;
        p1++;
    }
    p2=p1;
    while(p2<=10){
        if(letter[p2]==' ')break;
        p2++;
    }
    p3=p2+1;
    int p3l=p3;
    while(letter[p3l]==' ')p3l++;
    while(letter[p3]==' ')p3++;
    while(letter[p3]!=' '&&p3<=strlen(letter)){
        p3++;
    }
    p4=p3+1;
    int p4l=p4;
    while(letter[p4]==' ')p4++;
    while(letter[p4l]==' ')p4l++;
    while(letter[p4]!=' '&&p4<=strlen(letter)){
        p4++;
    }
    char vart[10],varname[1000],vard[1000];
    _strcpy(vart,letter,p1,p2-1);
    _strcpy(varname,letter,p3l,p3-1);
    _strcpy(vard,letter,p4l,p4-1);
    std::string tmp1=vart,tmp2=varname,tmp3=vard;
    // cout<<tmp1<<"@"<<tmp2<<"@"<<tmp3<<"@";
    yrmem[tmp2].variable_type=tmp1[2];
    if(tmp3!="yr")yrmem[tmp2].variable=tmp3;
    // if(tmp=="yri")
}

void yrsays(char letter[]) {
    int i1 = 0, i2 = strlen(letter), i3 = 0;
    while (letter[i1] != '(')i1++;
    if (letter[i1 + 1] == '\"') {
        while (letter[i2] != '\"')i2--;
        for (i3 = i1 + 2; i3 <= i2-1; i3++)std::cout << letter[i3];
        std::cout << std::endl;
    }else
    if (letter[i1] != '\"') {
        char message[1000];
        for (int i = 0; i < 1000; i++)message[i] = 0;
        // while (letter[i1]!='(')i1++;
        while (letter[i2] != ')')i2--;

        for (int i = i1 + 1; i < i2; i++) {
            message[i - i1 - 1] = letter[i];
            // cout<<message[i-i1-1]<<i-i1-1<<endl;
        }
        std::cout << yrmem[message].variable << std::endl;
    }
}

void yreat(char letter[]) {
    int i1 = 0, i2 = strlen(letter), i3 = 0; char message[1000];

    for (int i = 0; i < 1000; i++)message[i] = 0;
    while (letter[i1] != '(')i1++;
    while (letter[i2] != ')')i2--;

    for (int i = i1 + 1; i < i2; i++) {
        message[i - i1 - 1] = letter[i];
        // cout<<message[i-i1-1]<<i-i1-1<<endl;
    }
    message[strlen(message)]=',';message[strlen(message)+1]='\0';
    // cout<<message[0];
    // for(int i=0;i<strlen(message);i++)cout<<message[i];
    // cout<<endl<<message<<endl;
    int l=0,r=0,dou=0;char emp[10000];
    std::string value;
    for(int i=0;i<strlen(message);i++){
        if(message[i]==','){
            r=i-1;
            _strcpy(emp,message,l,r);
            l=i+1;r=l;
            std::cin>>value;std::cin.sync();
            yrmem[emp].variable = value;
            yrmem[emp].variable_type = pd_var_type(value);
        }
    }
}

int four_ope_i(std::string mvars,std::string rvars,char ope){
    // std::cout<<yrmem[mvars].variable;
    int l,r;
    if(pd_var_type(mvars)=='i')l=atoi(mvars.c_str());
    else l=atoi(yrmem[mvars].variable.c_str());
    if(pd_var_type(rvars)=='i')r=atoi(rvars.c_str());
    else r=atoi(yrmem[rvars].variable.c_str());
    switch (ope)
    {
    case '+':
        return l+r;
        break;
    case '-':
        return l-r;
        break;
    case '*':
        return l*r;
        break;
    case '/':
        return l/r;
        break;
    case '%':
        return l%r;
        break;
    default:
        break;
    }
}
float four_ope_f(std::string mvars,std::string rvars,char ope){
    // std::cout<<yrmem[mvars].variable;
    float l,r;
    if(pd_var_type(mvars)=='f')l=atof(mvars.c_str());
    else l=atof(yrmem[mvars].variable.c_str());
    if(pd_var_type(rvars)=='f')r=atof(rvars.c_str());
    else r=atof(yrmem[rvars].variable.c_str());
    switch (ope)
    {
    case '+':
        return l+r;
        break;
    case '-':
        return l-r;
        break;
    case '*':
        return l*r;
        break;
    case '/':
        return l/r;
        break;
    default:
        break;
    }
}
void operation(char letter[]){
    int symbol_times=0,symbol_position,equal_times=0,equal_position;
    for(int i=0;i<std::strlen(letter);i++){
        if(letter[i]=='+'||letter[i]=='-'||letter[i]=='*'||letter[i]=='/'||letter[i]=='^'||letter[i]=='%'){
            symbol_position=i;
            symbol_times++;
        }
        if(letter[i]=='='){
            equal_position=i;
            equal_times++;
        }
    }

    int l1=0,l2=equal_position+1,l3=symbol_position+1,r1=equal_position-1,r2=symbol_position-1,r3=strlen(letter)-4;
    char lvar[1000],mvar[1000],rvar[1000];
    _strcpy(lvar,letter,l1,r1);
    _strcpy(mvar,letter,l2,r2);
    _strcpy(rvar,letter,l3,r3);
    // std::cout<<lvar<<" "<<mvar<<" "<<rvar<<std::endl;
    // std::cout<<yrmem[lvar].variable_type<<" "<<yrmem[mvar].variable_type<<" "<<yrmem[rvar].variable_type<<std::endl;
    char opera=letter[symbol_position];
    int mvar_i=0,rvar_i;float mvar_f,rvar_f;
    std::string lvars=lvar,mvars=mvar,rvars=rvar;
    if(pd_var_type(lvars)=='i'||pd_var_type(lvars)=='f'){
        std::cout<<"The assigned variable must be a variable(最左边的得是个变量:("<<std::endl;
        return;
    } else {
        if(yrmem[mvars].variable_type=='i')yrmem[lvars].variable=_to_string(four_ope_i(mvars,rvars,opera));
        if(yrmem[mvars].variable_type=='f')yrmem[lvars].variable=_to_string(four_ope_f(mvars,rvars,opera));
        // if(yrmem[mvars].variable_type=='i'&&yrmem[rvars].variable_type=='i'){
        //     yrmem[lvars].variable=_to_string(four_ope_i(mvars,rvars,opera));
        // }else if(yrmem[mvars].variable_type=='f'&&yrmem[rvars].variable_type=='f'){
        //     yrmem[lvars].variable=_to_string(four_ope_f(mvars,rvars,opera));
        // }
    }
}

using std::string;  using std::map;
using std::stack;   using std::queue;
using std::cin;

typedef struct node
{
    double m_num;
    char m_op;
    bool m_flag;
}node;

// string g_Str;
stack<node> g_S;
queue<node> g_Q;
map<int, char> g_Op;

void Change(string g_Str){//中缀转后缀
    double num;
    node temp;
    for (string::size_type i = 0; i != g_Str.size();)
    {
        if(g_Str[i] >= '0' && g_Str[i] <= '9'){
            temp.m_flag = true; //标记是数字
            temp.m_num = g_Str[i++] - '0';//记录这个操作数的第一位
            while(i < g_Str.size() && g_Str[i] >= '0'&&  g_Str[i] <= '9'){//连续读入数字并按数位还原 原始数值
                temp.m_num = temp.m_num * 10 + (g_Str[i] - '0');
                i++;
            }
            g_Q.push(temp);//操作数压入后缀表达式队列
        }else{
            temp.m_flag = false;
            if(g_Str[i] == '(') {
                temp.m_op = g_Str[i];
                g_S.push(temp);//压入操作符栈
                i++;
            }else if(g_Str[i] == ')'){//一直弹出直到遇见左括号
                while(!g_S.empty() && (g_S.top().m_op != '(')){
                    g_Q.push(g_S.top());
                    g_S.pop();
                }
                g_S.pop();//把左括号也弹出
                i++;
            }else{
                //栈顶元素比操作符高，就把栈顶元素弹到后缀表达式中
                while(!g_S.empty() && g_Op[g_S.top().m_op] >= g_Op[g_Str[i]]){
                    g_Q.push(g_S.top());
                    g_S.pop();
                }
                temp.m_op = g_Str[i];
                g_S.push(temp);//压入操作符栈
                i++;
            }
        }
    }

    while(!g_S.empty()){//操作符栈中还有操作符弹到后缀表达队列中
        g_Q.push(g_S.top());
        g_S.pop();
    }

//        while(!g_Q.empty()) //打印后缀队列
//    {
//        if(g_Q.front().m_flag == true){
//            printf("%f ",g_Q.front().m_num);
//        }else{
//            printf("%c ", g_Q.front().m_op);
//        }
//        g_Q.pop();
//    }
//    printf("\n");
}

double Cal(string g_Str){ //计算后缀表达式
    node cur, temp; //temp记录 弹出栈后计算得到值的信息
    double num1,num2;//存储从栈中弹出的两个数值
    while(!g_Q.empty()){
        cur  = g_Q.front();
        g_Q.pop();
        if(cur.m_flag == true) {
            g_S.push(cur);
        }else{
            num2 = g_S.top().m_num;//弹出第二个操作数
            g_S.pop();
            num1 = g_S.top().m_num;//弹出第一个操作数
            g_S.pop();
            temp.m_flag = true;//临时记录操作数为数字
            if(cur.m_op == '+') temp.m_num = num1 + num2;
            else if(cur.m_op == '-') temp.m_num = num1 - num2;
            else if(cur.m_op == '*') temp.m_num = num1 * num2;
            else temp.m_num = num1 / num2;
            g_S.push(temp);//把计算得到的结果（该操作数）压入栈
        }
    }
    return g_S.top().m_num;//栈顶元素就是后缀表达式的值
}

string str_to_num(string mes){
    // std::cout<<mes<<" ";
    string out,emp;int t=0,r=0;bool ji[1000];
    memset(ji,0,sizeof(ji));
    for(int i=0;i<=mes.length();i++){
        if(mes[i]=='+'||mes[i]=='-'||mes[i]=='*'||mes[i]=='/'||mes[i]=='%'||mes[i]=='('||mes[i]==')'||(mes[i]>='0'&&mes[i]<='9')){
            // out+=mes[i];
            ji[i]=1;
        }
    }
    // for(int j=0;j<1000;j++)cout<<ji[j];
    for(int i=0;i<mes.length();i++){
        // cout<<out<<endl;
        if(mes[i]=='+'||mes[i]=='-'||mes[i]=='*'||mes[i]=='/'||mes[i]=='%'||mes[i]=='('||mes[i]==')'||(mes[i]>='0'&&mes[i]<='9'))out+=mes[i];
        else{
            r=i;t=0;
            while(!ji[r]&&r<mes.length()){r++;t++;}
            out+=yrmem[mes.substr(i,t)].variable;
            i+=t;i--;
        }
    }
    // std::cout<<out<<std::endl;
    return out;
}

int pd_(string g_Str){
    g_Op['+'] = g_Op['-'] = 1;
    g_Op['*'] = g_Op['/'] = 2;
    for (string::iterator it = g_Str.end(); it != g_Str.begin(); it--){
        if(*it == ' ') g_Str.erase(it);
    }
    while(!g_S.empty()) g_S.pop();//初始化栈，在下次计算开始时清空栈内容
    Change(g_Str);
    return Cal(g_Str);
}


int pd(char letter[]){
    int l1=3,r1=3,equal=3,l2,r2,kuoh=1;
    char lmess[1000],rmess[1000];
    while(letter[r1]!='='&&letter[r1+1]!='=')r1++;
    l2=r1+3,r2=l2;
    while(letter[r2+1]!=')'&&kuoh!=0){
        if(letter[r2+1]=='(')kuoh++;
        if(letter[r2+1]==')')kuoh--;
        r2++;
    }
    _strcpy(lmess,letter,l1,r1);
    _strcpy(rmess,letter,l2,r2);

    strcpy( lmess,str_to_num(lmess).c_str());
    strcpy( rmess,str_to_num(rmess).c_str());
    // cout<<lmess<<" "<<rmess;
    if(pd_(lmess)==pd_(rmess))return 1;
    else return 0;
    // return 0;
}



bool yf(char letter[]){
    if(pd(letter)) return 1;
    else return 0;
    // if(pd(letter)){
    //     int p=0;char runlet[1000];
    //     for(int i=0;i<strlen(letter);i++){
    //         if(letter[i]==' ')p=i+1;
    //     }
    //     _strcpy(runlet,letter,p,strlen(letter)-1);

    // }
    // else return;
}